home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Samples / Driver Samples / SCSI samples / SCSI 950629 / NCR_DriverProject / Src / PrepMemoryUtilities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  4.9 KB  |  157 lines  |  [TEXT/MPCC]

  1. /*                                PrepMemoryUtilities.c                                */
  2. /*
  3.  * PrepMemoryUtilities.c
  4.  * Copyright © 1994-95 Apple Computer Inc. All rights reserved.
  5.  */
  6. /*    .___________________________________________________________________________________.
  7.       | These routines simplify the computations needed for PrepareMemoryForIO. They        |
  8.       | are not specific to the framework driver.                                            |
  9.       |                                                                                    |
  10.       |    CheckpointIOTable        Call CheckpointIO for the specified IOPreparationTable    |
  11.       |                            CompareAndSwap is used to ensure that CheckpointIO        |
  12.       |                            is called once only -- this is probably overkill        |
  13.       |    CheckForContiguousPhysicalMapping    Scan a physical mapping table to ensure        |
  14.       |                            that the entire area is physically contiguous. Since    |
  15.       |                            the driver can call MemAllocatePhysicallyContiguous,    |
  16.       |                            this isn't really needed anymore.                        |
  17.       |    NextPageIsContiguous    Return TRUE if the page following the indexed page        |
  18.       |                            is physically contiguous to the argument page. This is    |
  19.       |                            used to build the longest-possible DMA request.            |
  20.       |    GetMapEntryCount        Given a logical address and area length, return the        |
  21.       |                            number of physical map entries that will be needed.        |
  22.       |    NextPageBaseAddress        Return the base of the physical page following the        |
  23.       |                            argument physical address. This is needed to determine    |
  24.       |                            contiguous physical mappings. It could be a macro.        |
  25.       |    PageBaseAddress            Return the base of the physical page containing this    |
  26.       |                            address (which may be a logical or physical address).    |
  27.       |                            This could be a macro.                                    |
  28.       |    ClearMemory                A general subroutine to clear a block of memory. It        |
  29.       |                            tries to be efficient.                                    |
  30.     .___________________________________________________________________________________.
  31. */
  32. #include "NCRDriverPrivate.h"
  33.  
  34. /*
  35.  * This is a slightly safer version of CheckpointIO that will invalidate the
  36.  * preparationID after it completes, and will not call CheckpointIO if the
  37.  * preparationID is already invalid.
  38.  */
  39. void
  40. CheckpointIOTable(
  41.         IOPreparationTable        *ioTable
  42.  
  43.     )
  44. {
  45.         OSStatus                osStatus;
  46.         IOPreparationID            preparationID;
  47.  
  48.         Trace(CheckpointIOTable);
  49.         while ((preparationID = ioTable->preparationID) != kInvalidID) {
  50.             if (CompareAndSwap(
  51.                     (UInt32) preparationID, kInvalidID, (UInt32 *) &ioTable->preparationID)) {
  52.                 osStatus = CheckpointIO(preparationID, kNilOptions);
  53.                 CheckStatus(osStatus, "\pCheckpointIO");
  54.                 break;
  55.             } /* If CompareAndSwap succeeds */
  56.         } /* Concurrent access loop */
  57. }
  58.  
  59.  
  60. /*
  61.  * This looks at the physical mapping table to ensure that the physical area
  62.  * is contiguous. The script and per-request tables must be contiguous and the driver
  63.  * will fail to initialize if this is not the case.
  64.  */
  65. OSErr
  66. CheckForContiguousPhysicalMapping(
  67.         const IOPreparationTable *ioTable
  68.     )
  69. {
  70.         ItemCount                i;
  71.         OSErr                    status;
  72.         
  73.         //** Trace(CheckForContiguousPhysicalMapping);
  74.         status = noErr;
  75.         for (i = 0; i < ioTable->mappingEntryCount - 1; i++) {
  76.             if (NextPageIsContiguous(ioTable->physicalMapping, i) == FALSE) {
  77.                 status = paramErr;
  78.                 break;
  79.             }
  80.         }
  81.         CheckStatus(status, "\pNon-contiguous physical mapping");
  82. #if 0
  83.         LogMemory(
  84.             &ioTable->physicalMapping[0],
  85.             ioTable->mappingEntryCount * sizeof (PhysicalAddress)
  86.         );
  87. #endif
  88.         return (status);
  89. }
  90.  
  91. /*
  92.  * Return the number of mapping tables that this area will require. There is one entry
  93.  * per page. Thus the result is the number of distinct pages in the area. areaLength
  94.  * should not be zero.
  95.  */
  96. ItemCount
  97. GetMapEntryCount(
  98.         void                    *areaBaseAddress,
  99.         ByteCount                areaLength
  100.     )
  101. {
  102.         ItemCount                result;
  103.         ByteCount                normalizedLength;
  104.         UInt32                    areaAddress;
  105.         
  106.         //** Trace(GetMapEntryCount);
  107.         areaAddress = (UInt32) areaBaseAddress;
  108.         normalizedLength = PageBaseAddress(areaAddress + areaLength - 1)
  109.                          - PageBaseAddress(areaAddress);
  110.         result = (ItemCount) (normalizedLength / gPageSize) + 1;
  111. #if 0 && USE_LOG_LIBRARY
  112.         WriteLogEntry(GLOBAL.logRecordPtr, 'GMap',
  113.             LogFormat5(kLogFormatAddress, kLogFormatUnsigned,
  114.                 kLogFormatUnsigned, kLogFormatUnsigned, kLogFormatString),
  115.             (UInt32) areaBaseAddress,
  116.             (UInt32) areaLength,
  117.             (UInt32) normalizedLength,
  118.             (UInt32) result,
  119.             "\pGetMapAreaCount"
  120.         );
  121. #endif
  122.         return (result);
  123. }
  124.  
  125. /*
  126.  * Clear a block of memory. This is optimized to use longword access whenever possible.
  127.  */
  128. void
  129. ClearMemory(
  130.         void                    *areaAddress,
  131.         register Size            byteCount
  132.     )
  133. {
  134.         register UInt8            *bytePtr;
  135. #define kWordSize    (sizeof (UInt32))
  136. #define kWordMask    (kWordSize - 1)
  137.  
  138.         //** Trace(ClearMemory);
  139.         bytePtr = (UInt8 *) areaAddress;
  140.         while ((((UInt32) bytePtr) & kWordMask) != 0 && byteCount > 0) {
  141.             *bytePtr++ = 0;
  142.             --byteCount;
  143.         }
  144.         while (byteCount >= kWordSize) {
  145.             *((UInt32 *) bytePtr) = 0;
  146.             bytePtr += kWordSize;
  147.             byteCount -= kWordSize;
  148.         }
  149.         while (byteCount > 0) {
  150.             *bytePtr++ = 0;
  151.             --byteCount;
  152.         }
  153. #undef kWordSize
  154. #undef kWordMax
  155. }
  156.  
  157.